package org.odefu.flash.display
{
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.filters.BitmapFilter;
	import flash.geom.Rectangle;

	public class BoundsUtil
	{
		public function BoundsUtil()
		{
			throw new Error("BoundsUtil is a static class!");
		}
		
		/**
		 * Gets the bounds for the current frame in the MovieClip.
		 */
		public static function getFrameBounds(mc:MovieClip):Rectangle
		{
			const bounds:Rectangle = getBounds(mc);
			addFilterBounds(bounds, mc);
			return bounds;
		}
		
		public static function getBounds(mc:DisplayObject):Rectangle
		{
			const bounds:Rectangle = mc.getBounds(mc.parent);
			bounds.x = Math.floor(bounds.x);
			bounds.y = Math.floor(bounds.y);
			bounds.width = Math.ceil(bounds.width);
			bounds.height = Math.ceil(bounds.height);
			return bounds;
		}

		public static function addFilterBounds(bounds:Rectangle, mc:DisplayObject):void
		{
			for (var i:int = 0; i < mc.filters.length; i++)
			{
				const filterBounds:Rectangle = getFilterBounds(getBounds(mc), mc.filters[i]);
				bounds.copyFrom(bounds.union(filterBounds));
			}
			
			if (mc is DisplayObjectContainer)
			{
				const container:DisplayObjectContainer = DisplayObjectContainer(mc);
				for (var j:int = 0; j < container.numChildren; j++)
				{
					addFilterBounds(bounds, container.getChildAt(j));
				}
			}
		}
		
		private static function getFilterBounds(bounds:Rectangle, filter:BitmapFilter):Rectangle
		{
			const data:BitmapData = new BitmapData(bounds.width, bounds.height, false);
			const filterBounds:Rectangle = data.generateFilterRect(data.rect, filter);
			data.dispose();
			return filterBounds;
		}
	}
}